/**
 * @file   PUTFILEAuthFile.java
 * @date   2012-12-5下午1:57:42
 * @author User
 */
package com.gzceb.zhgjj.model;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.gzceb.zhgjj.mina.MinaConstants;
import com.gzceb.zhgjj.util.PropertiesUtils;
import com.gzceb.zhgjj.util.Utils;
import com.gzceb.zhgjj.model.Constants;

/**
 * <p>PUTFILE授权文件处理类。</p>
 *
 * @date   2012-12-5下午1:57:42 
 * @author liqing
 * @description 主要用来处理错误文件的授权文件收发
 */
public class PUTFILEAuthFile {
	private  final Log logger = LogFactory.getLog(PUTFILEAuthFile.class);
	
	public String strPath;
	
	private String fileName;
	private String fileCont="";  //发送来的文件内容先保存在String中。
	
	
	public PUTFILEAuthFile(String strPath){
		this.strPath = strPath;
	}
	
	public void setFileName(String fileName){
		this.fileName = fileName;
	}
	
	/**
	 * 处理接收到的信息，保存成授权文件
	 * @param message String
	 * @return 响应结构体 String 
	 */
	public String ProcRcvFile(String message){
		String rspStr = "";
		// 如果发来的是1号结构体
		if(Constants.MSG_1_STRUCT.equals(message.substring(0, 6))){
			logger.info("begin receiving PUTFILE MSG_1:" + message);
			fileName = Utils.getFileName(message.substring(6));
			if("".equals(fileName)){
				rspStr = Constants.MSG_2_STRUCT + Constants.MSG_RSPCODE_REJECT;
				logger.debug("fileName is NULL, so rsp msg is: " + rspStr);
				// TODO 重启线程，保存操作记录：拒绝接收卸数错误文件
				return rspStr;
			}
			try{
				File file = new File(this.strPath + fileName);
				file.createNewFile();
				rspStr = Constants.MSG_2_STRUCT + Constants.MSG_RSPCODE_READY; // 准备就绪，同意接收
			}catch(Exception e){
				logger.error("Error happened when create file: " + this.strPath + fileName);
				// TODO 重启线程，保存操作记录：操作异常无法接收
				rspStr = Constants.MSG_2_STRUCT + Constants.MSG_RSPCODE_WRONG; // 操作异常，无法接收
			}
			
			return rspStr;
		}else if(Constants.MSG_3_STRUCT.equals(message.substring(0, 1))){
			// 如果发来的是3号结构体
			logger.info("begin receiving PUTFILE MSG_3. continue...");
			String flag = message.substring(7, 8);
			if(message.length() != Integer.parseInt(message.substring(1, 6))){
				//如果报文中记录的报文长度与实际长度不一致，则返回接收错误
				logger.error("Error, message length is: " + Integer.parseInt(message.substring(1, 6))
						+ " actual length is : " + message.length());
				rspStr = Constants.MSG_4_STRUCT + Constants.MSG_RSPCODE_WRONG;
				// TODO 重启线程，保存操作记录：接收错误，报文长度与实际不一致
				return rspStr;
			}
			if(Constants.MSG_RSPCODE_CONTINUE.equals(flag)){
				// 如果还有后续文件数据发送
				fileCont += message.substring(8);
				logger.info("continue...");
				rspStr = Constants.MSG_4_STRUCT + Constants.MSG_RSPCODE_NEXT;
				return rspStr;
			}else if(Constants.MSG_RSPCODE_LAST.equals(flag)){
				// 如果是最后一个包，则将缓冲的内容写入文件
				fileCont += message.substring(8);
				// 开始写入文件
				BufferedWriter writer = null;
				logger.info("begin to write file：" + fileName);
				try{
					writer = new BufferedWriter(new FileWriter(this.strPath + fileName));
					writer.write(fileCont);	
					rspStr = Constants.MSG_4_STRUCT + Constants.MSG_RSPCODE_OVER;
					// TODO 重启线程，保存操作记录：接收卸数错误授权文件完成
				}catch(IOException ie){
					logger.error("error happend when write the file " + fileName + "\n"+ ie.getMessage());
					rspStr = Constants.MSG_4_STRUCT + Constants.MSG_RSPCODE_WRONG;  // 写文件有错的话，返回接收错误给中心系统
					// TODO 重启线程，保存操作记录：写文件出错，错误返回
				}finally{
					if (writer != null) {
						try {
							writer.close();
						} catch (Exception ec) {
							rspStr = Constants.MSG_4_STRUCT + Constants.MSG_RSPCODE_WRONG;  // 写文件有错的话，返回接收错误给中心系统
							// TODO 重启线程，保存操作记录：写文件出错，错误返回
						}
					}
				}
				return rspStr;
				
			}else if(Constants.MSG_RSPCODE_WRONG.equals(flag)){
				// 如果是发送错误，则返回接收错误
				logger.info("Error, receive an error info in message.");
				rspStr = Constants.MSG_4_STRUCT + Constants.MSG_RSPCODE_WRONG;
				// TODO 重启线程，保存操作记录, 接收文件错误
				return rspStr;
			}
		}
		// 如果报文全不是上面的情况，则报文有错
		rspStr = Constants.MSG_4_STRUCT + Constants.MSG_RSPCODE_WRONG;
		return rspStr;
	}
	
	
	/**
	 * 处理授权反馈文件，发送给中心系统
	 * @param message String
	 * @return 响应结构体 String 
	 */
	public String ProcRspFile(String message){
		String rspStr = "";
		// 先接收到中心发来的1号体文件名请求
		if( Constants.MSG_1_STRUCT.equals(message.substring(0, 6)) ){
			logger.info("begin receiving PUTFILE MSG_1:" + message + "\n" + "begin reading local file");
			fileName = Utils.getFileName(message.substring(6));
			if("".equals(fileName)){
				rspStr = Constants.MSG_2_STRUCT + Constants.MSG_RSPCODE_REJECT;
				logger.debug("fileName is NULL, so rsp msg is: " + rspStr);
				// TODO 重启线程，保存操作记录：请求的卸数错误文件不存在，反馈错误
				return rspStr;
			}
			BufferedReader br = null;
			try{
				br = new BufferedReader(new FileReader(strPath + fileName));
				String tmpStr = null;
				while( (tmpStr = br.readLine()) != null){
					fileCont += tmpStr;
					fileCont += System.getProperty("line.separator");
				}
				logger.info("响应文件读取完毕。文件名：" + fileName);
				
				rspStr = Constants.MSG_2_STRUCT + Constants.MSG_RSPCODE_READY; // 准备就绪，同意接收
			}catch(Exception e){
				logger.error("Error happened when create file: " + this.strPath + fileName);
				rspStr = Constants.MSG_2_STRUCT + Constants.MSG_RSPCODE_WRONG; // 操作异常，无法接收
				// TODO 重启线程，保存操作记录：读取卸数错误响应文件报错，反馈错误
			}
			
			return rspStr;
		}else if( Constants.MSG_4_STRUCT.equals(message.substring(0, 6)) ){
			// 如果发来的是4号结构体，则判断
			logger.info("begin receiving PUTFILE MSG_4:" + message);
			String flag = message.substring(6, 7);
			if( Constants.MSG_RSPCODE_NEXT.equals(flag) ){
				// 接收成功，准备接下一个
				rspStr = getRspString();
				return rspStr;
			}else if( Constants.MSG_RSPCODE_OVER.equals(flag) ){
				// 如果接收正常结束, 返回结束标识给上层代码作处理
				rspStr = MinaConstants.F_OVER.getValue();
				// TODO 重启线程，保存操作记录：卸数错误文件响应文件反馈成功。
				return rspStr;
			}else if( Constants.MSG_RSPCODE_WRONG.equals(flag)){
				// 如果接收错误,返回结束标识给上层代码作处理
				rspStr = MinaConstants.F_OVER.getValue();
				// TODO 重启线程，保存操作记录：发送卸数错误文件响应文件失败，接收方反馈为失败。
				return rspStr;
			}
		}
		return rspStr;
		
	}
	
	/**
	 * 从反馈文件内容中提取每次需要发送的定长字符串用来填充3号结构体
	 * @param fileCont
	 * @return 3号结构体 String
	 */
	public String getRspString(){
		String rspStr;
		try{
			// 如果文件内容长度小于3号结构体要求数据大小1024字节, 直接返回这段字符串,最后一个包
			if(Constants.MSG_3_DATABUF >= fileCont.length()){
				rspStr = Constants.MSG_3_STRUCT 
						+ Utils.intToString(Constants.MSG_3_DGLENGTH + fileCont.length(), 5)
						+ Constants.MSG_RSPCODE_LAST
						+ fileCont;
			}
			// 如果大于1024，返回1024个字节，并缩短 fileCont,还有后续包
			String tmpStr = fileCont.substring(0, Constants.MSG_3_DATABUF);
			fileCont = fileCont.substring(Constants.MSG_3_DATABUF);
			rspStr = Constants.MSG_3_STRUCT
					+ Utils.intToString(Constants.MSG_3_DGLENGTH + tmpStr.length(), 5)
					+ Constants.MSG_RSPCODE_CONTINUE
					+ tmpStr;
		}catch(Exception e){
			logger.error("error happened when create 3rd Struct Msg. " 
						+ "\n" + e.getMessage());
			rspStr = Constants.MSG_3_STRUCT
					+ Utils.intToString(Constants.MSG_3_DGLENGTH, 5)
					+ Constants.MSG_RSPCODE_WRONG;
		}
		
		return rspStr;
		
	}
	
	
	
	public static void main(String[] args){
		PUTFILEAuthFile pf = new PUTFILEAuthFile(PropertiesUtils.getValue("destPath_PFAuth"));
		//String tst = pf.test("100086abcdefddfessdf") ;
	}
}


